///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Defines the maximum sequentialwriting length. The number must greater than or equal to 3. 
//If number equal to 3, it means using radom writing.
//
//  <START> <CHIP ADDR> <DATA> <DATA> <DATA> <STOP>
//                       
//If number greater than 3, it means using sequential writing.(Burst Mode) , say length is 5. the i2c
// data will like,
//  <START> <CHIP ADDR> <DATA> <DATA> <DATA> <DATA> <DATA><STOP>
//
#define MAX_I2C_SEQUENTIAL_WRITE_LEN    3    


#define EEPROM_PAGE_SIZE    128    //Specifies the EEPROM page size in bytes. ST M24M01 ->128, ATMEL -> 256 bytes.

//If defined, it downloads firmware to EEPROM, Otherwise it downloads firmware to cx2070x memory directly.
#define DOWNLOAD_EEPROM       1



///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Files for windows.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "includes_fw.h"
#include "config_fw.h"
#include "mmp_lib.h"
#include "os_wrap.h"
#include "lib_retina.h"

#include "mmpf_pll.h"
#include "mmpf_i2cm.h"
#include "mmp_reg_gbl.h"
#include "mmp_reg_gpio.h"
#include "mmpf_system.h"
#include "mmpd_system.h"


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Files for cx2070x
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "cxpump.h"
//#include "cx2070x_rom.h"
//#include "cx2070x_fw.h"
#include "cx2070x_download.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// lib Files for cx2070x.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

#if (SUPPORT_CNXT_FW_DOWNLOADING_EEPROM)

MMPF_I2CM_ATTRIBUTE uAudioI2cmAttribute1 =  {MMPF_I2CM_ID_0, 0x14, 16, 8, 0, MMP_FALSE, MMP_FALSE, MMP_FALSE, MMP_FALSE, 0, 0, 3, MMPF_I2CM_SPEED_HW_250K, NULL, NULL};

// i2c/SPI control function.
void* OpenI2cDevice();
void CloseI2cDevice(void* hI2cDevice);
int I2cWrite(void* hI2cDevice, unsigned char ChipAddr, unsigned long cbBuf, unsigned char* pBuf);
int I2cWriteThenRead(void* hI2cDevice, unsigned char ChipAddr, unsigned long cbBuf,
    unsigned char* pBuf, unsigned long cbReadBuf, unsigned char*pReadBuf);

/*
* Return the size of the specified file, in bytes.
*/

#ifndef true
#define true 1
#endif

#define FW_TO_RAM 0
#define FW_TO_EEPROM 1

unsigned char *ChannelFW = (unsigned char *) 0x1100000;
unsigned char *ChannelROM = (unsigned char *) 0x1600000;  //yidongq 1100000
extern MMP_ULONG USBFirmwareBinSize ;
void MMPF_CX2070xDownload(void)
{
    
    int                 errcode;
    unsigned long       cbFileSize = 0;   
    unsigned char       *pRomData =  NULL;
    unsigned char       *pEepromData = NULL;
    unsigned long       cbEEpromData;
    void* hDevice =    OpenI2cDevice();
    //if(hDevice == INVALID_HANDLE_VALUE|| hDevice == NULL)
    if( hDevice == NULL)
		
    {
        RTNA_DBG_Str3( "Searial device is not present.\n");
        
    }

    //
    // setup the i2c callback function.
    //
    SetupI2cWriteCallback( (void *) hDevice, (fun_I2cWrite) I2cWrite,MAX_I2C_SEQUENTIAL_WRITE_LEN);
    SetupI2cWriteThenReadCallback( (void *) hDevice, (fun_I2cWriteThenRead) I2cWriteThenRead);
    pRomData = (MMP_UBYTE *)ChannelFW;
	pEepromData = (MMP_UBYTE *)ChannelROM; 
	cbEEpromData=USBFirmwareBinSize;
    //
    // Download FW.
    //
    //If the operation completes successfully, the return value is ERRNO_NOERR.
    //Otherwise, return ERRON_* error code. 

#ifdef DOWNLOAD_EEPROM
    //Download firmware to EEPROM.
        errcode = DownloadFW(pRomData,2,pEepromData,cbEEpromData,EEPROM_PAGE_SIZE);  //yidongq 1-> 2

//    errcode = DownloadFW(ChannelFW,1,ChannelROM,sizeof(ChannelROM),EEPROM_PAGE_SIZE);
#else
    //Download firmware to cx2070x ram directly.
    errcode = DownloadFW(pRomData,0,0,0,0);
#endif

    // close control interface.
    CloseI2cDevice(hDevice);

	RTNA_DBG_Str3("Done \n");
    
}


void* OpenI2cDevice()
{
	AITPS_GBL   pGBL = AITC_BASE_GBL;
    MMP_USHORT clock0 = 0x0, clock1 = 0x0;
	RTNA_DBG_Str3("MMPF_CX2070xDownload Start... \n");
    //
    // setup the i2c callback function.
    //RTNA_DBG_Str3("volume :");RTNA_DBG_Byte3(volume);RTNA_DBG_Str3("\r\n");

	clock0 = pGBL->GBL_CLK_DIS0;
	clock1 = pGBL->GBL_CLK_DIS1;
	pGBL->GBL_CLK_DIS0 &= (~GBL_CLK_VI_DIS);
	pGBL->GBL_CLK_DIS1 &= (~GBL_CLK_I2C_DIS);

	mxinit((void*)0x1400000, 0x200000);
	MMPF_I2cm_Initialize(&uAudioI2cmAttribute1);		

    return ( void*) &uAudioI2cmAttribute1;
}

void CloseI2cDevice(void* hI2cDevice)
{
    
}

int I2cWrite(void* hI2cDevice, unsigned char ChipAddr, unsigned long cbBuf, unsigned char* pBuf)
{
	MMP_USHORT usAdress;
	MMP_USHORT i,j;

	usAdress = (pBuf[0]<<8) + pBuf[1];
#if 1
	for(i=0;i<(cbBuf-2);i++)
	{
		//usData[i]=(MMP_USHORT)ucData[i+2];
		//RTNA_DBG_PrintShort(0, usAdress+i);
		
		MMPF_I2cm_WriteReg(&uAudioI2cmAttribute1,usAdress+i, (MMP_USHORT)(pBuf[i+2]));
		//RTNA_DBG_Str3("  W");RTNA_DBG_Short3(usAdress+i);RTNA_DBG_Byte3(pBuf[i+2]);
	}
#else	
	MMPF_I2cm_WriteReg((MMPF_I2CM_ATTRIBUTE*)hI2cDevice,usAdress, (MMP_USHORT)pBuf[2]);
	//RTNA_DBG_Str3("  W");RTNA_DBG_Short3(usAdress);RTNA_DBG_Byte3(pBuf[2]);
#endif
    //return MMP_ERR_NONE;
    return true; // return true if the operation completes successfully.
}



int I2cWriteThenRead(void* hI2cDevice, unsigned char ChipAddr, unsigned long cbBuf,
                     unsigned char* pBuf, unsigned long cbReadBuf, unsigned char*pReadBuf)
{
	MMP_USHORT usAdress, *uspData,usData=0;
	MMP_ULONG i;
	MMP_UBYTE ucCount;

	usAdress = ((MMP_USHORT)(pBuf[0]<<8) +(MMP_USHORT)(pBuf[1]));

	MMPF_I2cm_ReadReg((MMPF_I2CM_ATTRIBUTE*)hI2cDevice,usAdress, &usData);

	*pReadBuf=(MMP_UBYTE)usData;
	//RTNA_DBG_Str3("  R");RTNA_DBG_Short3(usAdress);RTNA_DBG_Byte3(*pReadBuf);
    return true; // return true if the operation completes successfully.
}
#endif

